//
// Created by 13289204862@163.com on 2024/5/9.
//

#ifndef FOC_SERIAL_H
#define FOC_SERIAL_H

#include <stdint.h>
#include "mc_task.h"


// CAN ID 11 bit high to low
#define ID_ECHO_BIT         0x400 // 1 bit
#define ID_NODE_BIT         0x3E0 // 5 bit
#define ID_CMD_BIT          0x01F // 5 bit

#define IS_ECHO(can_id)     (can_id & ID_ECHO_BIT)
#define GET_NODE_ID(can_id) ((can_id & ID_NODE_BIT) >> 5)
#define GET_CMD(can_id)     (can_id & ID_CMD_BIT)



typedef enum eSerialCmd
{
    CAN_CMD_MOTOR_DISABLE = 0,
    CAN_CMD_MOTOR_ENABLE,

    CAN_CMD_SET_TORQUE,
    CAN_CMD_SET_VELOCITY,
    CAN_CMD_SET_POSITION,

    CAN_CMD_CALIB_START,
    CAN_CMD_CALIB_REPORT,
    CAN_CMD_CALIB_ABORT,

    CAN_CMD_ANTICOGGING_START,
    CAN_CMD_ANTICOGGING_REPORT,
    CAN_CMD_ANTICOGGING_ABORT,

    CAN_CMD_SET_HOME,
    CAN_CMD_ERROR_RESET,
    CAN_CMD_GET_STATUSWORD,
    CAN_CMD_STATUSWORD_REPORT,

    CAN_CMD_GET_VALUE_1,
    CAN_CMD_GET_VALUE_2,

    CAN_CMD_SET_CONFIG,
    CAN_CMD_GET_CONFIG,
    CAN_CMD_SAVE_ALL_CONFIG,
    CAN_CMD_RESET_ALL_CONFIG,

    CAN_CMD_SYNC,
    CAN_CMD_HEARTBEAT,

    CAN_CMD_GET_FW_VERSION = 28,

    CAN_CMD_DFU_START,
    CAN_CMD_DFU_DATA,
    CAN_CMD_DFU_END,
} SerialCmd_t;

typedef enum eDataType
{
    DATA_TYPE_TORQUE = 0,
    DATA_TYPE_ENCODER_VEL,
    DATA_TYPE_ENCODER_POS,
    DATA_TYPE_IQ_FILT,
    DATA_TYPE_VBUS_FILT,
    DATA_TYPE_IBUS_FILT,
    DATA_TYPE_POWER_FILT
} DataType_t;


typedef struct SerialFrame
{
    uint32_t head : 8; // 帧头，固定为0xAA
    uint32_t id : 16;
    uint32_t dlc : 8;
    uint8_t  data[8];
    uint32_t crc;
} SerialFrame_t;


void CAN_set_node_id(uint8_t nodeID);
void CAN_comm_loop(void);
void CAN_reset_rx_timeout(void);
void CAN_reset_tx_timeout(void);

void CAN_receive_callback(uint8_t* data, int len);

void CAN_tx_statusword(tMCStatusword statusword);

// only used in one NVIC
void CAN_calib_report(int32_t step, uint8_t *data);
void CAN_anticogging_report(int32_t step, int32_t value);


#endif //FOC_SERIAL_H
